Memory manager BORLNDMM.DLL, padajici program pri uvolneni DLL na Win95
Otázka od: Radek Kučera
24. 9. 2002 13:41
Win2000, Delphi6, MSSQL2000, Adonis
Dobry den,
v programu pouzivam volani DLL. Pri uvolneni DLL ( FreeLibrary(LibHandle) )
na OS WIN95 vyskoci chyba: "Program provedl neplatnou operaci a bude
ukoncen".
Na Win98, Win2000 i WinXP to funguje spravne.
I na W2000 me program padal v runtime modu (z vyvojoveho prostredi
fungoval), pokud jsem pouzival BORLNDMM.DLL : verze: 6.0.6.163 velikost:
22016 z 22.5.2001 8:00 z Delphi6. Kdyz jsem ji nahradil: BORLNDMM.DLL :
verze: 5.0.12.34 velikost: 13312 z 31.1.2000 5:00, funguje program spravne.
Na Win95 pada, i kdyz jsem zkusil BORLNDMM.DLL z Delphi4, ci pridal
DELPHIMM.DLL z Delphi4.
Muzete mne nekdo poradit, jak vyresit problem uvolneni DLL na Win95 ?
Prikladam ukazku pouziti:
procedure _SpustModul(...);
var
LIBHandle:THandle;
Run:TRun;
DataRun:TDLL;
HandleRun:THandle;
NazevDLL:string;
FceDLL :string;
Modul : String;
begin
FceDll :='RunDllDetail';
HandleRun:=Application.Handle;
//Spuštění vybraného modulu(dll souboru)
LibHandle:=0;
@Run:=nil;
try
LibHandle:=Loadlibrary(PChar(NazevDLL));
@Run:=GetProcAddress(LibHandle,PChar(FceDll));
if not (@Run=nil) then
finally
if LibHandle <> 0 then
begin
FreeLibrary(LibHandle); //!!! A tady to pada na Win95 !!!
end;
end;
end;
Predem dekuji za odpovedi
Radek Kucera
Odpovedá: Petr Vones
24. 9. 2002 18:17
Win95
From: "Radek Kučera" <raku@foresta.cz>
> I na W2000 me program padal v runtime modu (z vyvojoveho prostredi
> fungoval), pokud jsem pouzival BORLNDMM.DLL : verze: 6.0.6.163 velikost:
Co to napsat tak aby pouziti BORLNDMM.DLL nebylo vubec nutne.
Petr Vones
Odpovedá: Dalibor Toman
24. 9. 2002 15:37
Win95
> FreeLibrary(LibHandle); //!!! A tady to pada na Win95 !!!
1) nez pouzivat manazer pameti pro sdileni pameti s DLLkem je asi
lepsi to DLL napsat tak, aby jej nepoutrebovalo (cili nikdy
neuvolnovat procesem pamet alokovanou DLLkem a naopak)
2) pokud pouzivas COMy v DLL pak za urcitych podminek to bude v
FreeLibrary padat taky
D. Toman
Odpovedá: Radek Kučera
25. 9. 2002 10:39
Win95
> Co to napsat tak aby pouziti BORLNDMM.DLL nebylo vubec nutne.
>
Myslim si, ze pouziti BORLNDMM.DLL je nutne, nebot v predanych parametrech
do DLL je typ "packed record" se stringy.
Mirne doplnena procedura o dalsi kus zdroje, ktery jsem v minulem mailu pro
prehlednost vynechal:
type
// definice pro predavana data
TDLL = packed record
Database:TAdoDataBase;
Zkratka : String;
UO : String;
Regcis:Integer;
DT_Hlavni:String;
DT:String;
Poradi:Integer;
ModPrace:Char;
navrat:Integer;
end;
// funkce pro komunikaci mazi master a DLL
TRUN = function(AHandle:THandle;var DLL:TDLL):Boolean;stdcall;
TF_DLL = class(TForm)
ADODatabaseParadox: TADODatabase;
MasterDataBase: TADODatabase;
procedure FormCreate(Sender: TObject);
end;
procedure _SpustModul(...);
var
LIBHandle:THandle;
Run:TRun;
DataRun:TDLL;
HandleRun:THandle;
NazevDLL:string;
FceDLL :string;
Modul : String;
begin
FceDll :='RunDllDetail';
// naplneni predavanych parametru
application.createform(tF_DLL,F_DLL);
DataRun.Database := F_DataModule.ADODatabase;
DataRun.UO :=
Trim(F_DataModule.ADODS_Zadost.FieldByName('UO').AsString);
DataRun.RegCis :=
F_DataModule.ADODS_Zadost.FieldByName('RegCis').AsInteger;
DataRun.DT_hlavni :=
F_DataModule.ADODS_Zadost.FieldByName('DT_hlavni').AsString;
DataRun.Zkratka := Copy(F_UvodniFormular.G_Zkratka,1,10) {'JDB'};
DataRun.ModPrace := ModPrace;
// naplneni handlu z duvodu ukonveni master aplikace
HandleRun:=Application.Handle;
//Spusteni vybraneho modulu(dll souboru)
LibHandle:=0;
@Run:=nil;
try
LibHandle:=Loadlibrary(PChar(NazevDLL));
@Run:=GetProcAddress(LibHandle,PChar(FceDll));
if not (@Run=nil) then
finally
if LibHandle <> 0 then
begin
FreeLibrary(LibHandle); //!!! A tady to pada na Win95 !!!
end;
end;
end;
Predem dekuji za rady,
Radek Kucera
Odpovedá: Dalibor Toman
25. 9. 2002 13:39
Win95
> > Co to napsat tak aby pouziti BORLNDMM.DLL nebylo vubec nutne.
> >
>
> Myslim si, ze pouziti BORLNDMM.DLL je nutne, nebot v predanych
parametrech
> do DLL je typ "packed record" se stringy.
samozrejme je nutne podobne cunarny eliminovat - staci zajistit, ze v
predanych paremetrech (dynamicky alokovanych castech) nebudou
provadeny zmeny.
> Mirne doplnena procedura o dalsi kus zdroje, ktery jsem v minulem
mailu pro
> prehlednost vynechal:
>
> type
> // definice pro predavana data
> TDLL = packed record
> Database:TAdoDataBase;
> Zkratka : String;
> UO : String;
> Regcis:Integer;
> DT_Hlavni:String;
> DT:String;
> Poradi:Integer;
> ModPrace:Char;
> navrat:Integer;
> end;
urcite by AnsiStringa sla nahradit napriklad ShortStringy nebo PChar
buffery (array[0..x] of char). I v Databazi mas zrejme definovanou max
delku uvedenych retezcu - cili neni problem nahjradit AnsiString.
Pokud se AnsiStringu nechces/nemuzes vzdat pak je nutn zajistit, ze
pametove operace pro ne budou probihat vzdy bud v DLL nebo v aplikaci.
Napriklad ma-li DLL naplnit stringa, pak je musi aplikace pouzivat
jako readonly a po te co je uz nepotrebuje by se mela zavolat funkce z
DLL, ktera ansistringa dealokuje (xy.Zkratka := '')
D. Toman